package com.dc.gameserver.serverCore.service.battle;

import com.dc.gameserver.baseConfig.Config;
import com.dc.gameserver.extComponents.utilsKit.util.random.Rnd;
import com.dc.gameserver.hardCode.CardType;
import com.dc.gameserver.serverCore.model.gamemodel.LevelModel;
import com.dc.gameserver.serverCore.model.gamemodel.SkillModel;
import com.dc.gameserver.serverCore.model.gamemodel.script.ScriptFactory;
import com.dc.gameserver.serverCore.service.character.GameCharacter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author 石头哥哥
 *         Date: 13-11-28</br>
 *         Time: 下午4:07</br>
 *         Package: com.dc.gameserver.serverCore.service</br>
 *          注解：   游戏规则计算公式类
 *          五行相克 ：   金-> 木-> 土-> 水-> 火->金
 *                        1    2    3    4    5  1
 *
 *          1.role五行同玩家修炼的功法有关，其中功法来自秘籍(技能书 神识书 功法书  具体秘籍类型有type字段区分) -->element
 *          2.monster 五行属性：来子配置文件的 fiveType
 *
 */
public class GameFormula {


    private static final Logger LOGGER= LoggerFactory.getLogger(GameFormula.class);

    /**rates array**/
    public static float[] Rates=new float[4];


    /**
     *  groupID 一致的为一套
     *  成套功法书的灵气加成计算方式
     * @param bookNum    一套功法书已使用的本数
     * @param StorePercent    灵气存储百分比
     * @return  （一套功法书已使用的本数 - 1）* 每多一本功法书增加的灵气存储百分比
     */
    public static double LingQiPercnet(int bookNum,double StorePercent){
        return  ((bookNum- 0x1)*StorePercent);
    }

    /**
     *  灵气存储上限
     * @param allStoreLingQiLimit   已使用的所有功法书的灵气存储上限之和    num
     * @param allStorePercent       已使用的成套功法书的灵气存储百分比之和  ---（一本功法书增加的灵气存储百分比）
     * @return   灵气存储上限      = 已使用的所有功法书的灵气存储上限之和*（1+已使用的成套功法书的灵气存储百分比之和）
     */
    public static int allLingQiLimit(int allStoreLingQiLimit,double allStorePercent){
           return (int) (allStoreLingQiLimit*(1+allStorePercent));
    }


    /**
     * 客户端发起任何需要改变神识值的请求时
     * 获取自动恢复神识值间隔 soulRecoveryInitial 恢复的神识值
     * @param time1   当前时间戳
     * @param time2   之前记录的时间戳
     * @return
     */
    public static long[] autoRecoverySoul(long time1 ,long time2,int recoverySoul){
        long[] t_array=new long[2];
        //取整，计算已经走过的时间 t'=Δt*timeInitial
        long tempTime=(time1-time2)/Config.DEFAULT_VALUE.GAME_VALUE.soulRecoveryInitial;       //n和 timeInitial时间
        t_array[0]=tempTime*Config.DEFAULT_VALUE.GAME_VALUE.soulRecoveryInitial;  //矫正时间
        t_array[1]= (int)tempTime*recoverySoul; //恢复值
        return t_array;
    }

    /**
     * lastTime=soulRecoveryInitial-SoulGoneTime(t1,t2);
     * 神识恢复已经走过的时间
     * @param time1     当前时间点
     * @param time2     矫正时间点
     * @return   返回下恢复慢的满的剩余时间
     * (当前时间点-之前记录的时间点) % 恢复间隔
     */
    public static long SoulGoneTime(long time1,long time2){
      return (time1-time2)%Config.DEFAULT_VALUE.GAME_VALUE.soulRecoveryInitial;
    }


    /**
     * lastTime=spriteFullInitial-SpriteGoneTime(t1,t2);
     * @param time1
     * @param time2
     * @return
     */
    @Deprecated
    public static long SpriteGoneTime(long time1,long time2){
        return (time1-time2)%Config.DEFAULT_VALUE.GAME_VALUE.spriteFullInitial;
    }


    /**
     * 单位世间转换的灵气量
     * @param PerMinuteCreat1   灵脉单位时间转化的灵气量
     * @param PerMinuteCreat2   灵泉单位时间转化的灵气量
     * @param spiritTransifer   蒲团单位时间转化率
     * @return   SpriteCreatPeMin
     */
    public static int SpriteCreatPeMin(int PerMinuteCreat1,int PerMinuteCreat2,double spiritTransifer){
        return (int) ((PerMinuteCreat1+PerMinuteCreat2)*spiritTransifer);
    }


    /**
     * 将时间戳转化为分
     * @param time
     * @return
     */
    public static double coverTimeToMinutines(long time){
         return  time/ 0xea60;
    }

    /**
     * 获取card类型
     * @return
     */
    public static int getCardType(){
        //迭代Rate，if whichRate<=nextValue&&>preValue;will be break;
        //System.out.println("("+preValue+","+nextValue+"]");
        float tempRate=0;
        float whichRate=Rnd.newInstance(Rnd.RandomType.UNSECURE_VOLATILE).nextFloat();//return 0~1
        float preValue=0;
        float nextValue=0;
        for(float rate:Rates){
            nextValue=preValue+rate;
            if (whichRate>preValue&&whichRate<=nextValue){
                 //当前的区间在rate;
                tempRate=rate;
                break;
            }
            preValue=nextValue;
        }
        if (tempRate==0){
            throw new IllegalArgumentException("rate all is not 1, please check config");
        }
        if (tempRate==GameFormula.Rates[0]){
            return CardType.SOUL_TYPE.getType();
        }else if (tempRate==GameFormula.Rates[1]){
            return CardType.DEFENCE_TYPE.getType();
        }else if (tempRate==GameFormula.Rates[2]){
            return CardType.ATTACK_TYPE.getType();
        } else {
            return CardType.MAGIC_TYPE.getType();
        }
    }

   /******************************************************************************************************************/
    /**
     * 物品属性加层
     * @param BaseAttr   基础属性
     * @param currentStrengthLevel 当前强化等级
     * @param growUpAttr    成长属性
     * @param currentPinJie     当前品阶
     * @param basePinJie     基础品阶
     * @param PinJieModulus  品阶差系数
     * @param currentPinZhi   当前品质
     * @param basePinZhi        基础品质
     * @param PinZhiModulus     品质差系数
     * @return    装备属性=（（基础属性+（当前强化等级-1）*成长属性）*（1+（当前品阶-基础品阶）*品阶差系数）*（1+（当前品质-基础品质）*品质差系数）
     */
    public static double goodsAttr(double BaseAttr,int currentStrengthLevel,double growUpAttr,
                                    int currentPinJie,int basePinJie,double PinJieModulus,
                                    int currentPinZhi,int basePinZhi,double PinZhiModulus){
        return (BaseAttr+(currentStrengthLevel-1)*growUpAttr)
                *(1+(currentPinJie-basePinJie)*PinJieModulus)
                *(1+(currentPinZhi-basePinZhi)*PinZhiModulus);
    }

    /**
     * 获取角色的技能属性
     * @param BaseAttr    基础属性
     * @param currentPinJie   当前品阶
     * @param basePinJie      基础品阶
     * @param growUpAttr       成长属性
     * @return    人物技能属性=（基础属性+（当前品阶-基础品阶）*成长属性）
     */
    public static double getRoleSkillAttr(double BaseAttr,int currentPinJie,int basePinJie,double growUpAttr){
         return BaseAttr+(currentPinJie-basePinJie)*growUpAttr;
    }

    /**
     * 获取怪物技能属性
     * @param BaseAttr  基础属性
     * @param magicLevel  技能等级
     * @param growUpAttr  成长属性
     * @return 怪物技能属性=基础属性+（技能等级-1）*成长属性
     */
    public static double getMonsterSkillAttr(double BaseAttr,int magicLevel,double growUpAttr){
        return    BaseAttr+(magicLevel-1)*growUpAttr;
    }


    /**
     * 人物技能熟练度
     * @param skillUseTimes    技能使用次数
     * @param skillfulHigth     技能熟练最高值
     * @return  人物技能熟练度=Math.max((技能使用次数*技能熟练成长系数)/100,技能熟练最高值)
     */
    public static double getRoleSkillProficiency(int skillUseTimes,double skillfulHigth){
        return  getRoleSkillProficiency(skillUseTimes,0.05, 0.5);
    }

    /**
     * 人物技能熟练度
     * @param skillUseTimes    技能使用次数
     * @param skillProficiencyGrowUpModulus    技能熟练成长系数
     * @param skillfulHigth     技能熟练最高值
     * @return  人物技能熟练度=Math.max((技能使用次数*技能熟练成长系数)/100,技能熟练最高值)
     */
       public static double getRoleSkillProficiency(int skillUseTimes,double skillProficiencyGrowUpModulus,double skillfulHigth){
             return Math.max((skillUseTimes * skillProficiencyGrowUpModulus) / 0x64, skillfulHigth);
       }

    /**
     * 人物使用技能法力消耗
     * @param skillBaseExpend     技能基础消耗
     * @param skillProficiency     技能熟练度
     * @return    人物技能法力消耗=技能基础消耗*（1-技能熟练度）
     */
      public static double roleUseSkillExpendMagic(int skillBaseExpend,double skillProficiency){
            return skillBaseExpend*(1-skillProficiency);
      }

    /**
     * monster  使用技能法力消耗
     * @param skillBaseExpend      技能基础消耗
     * @param monsterMagicLevel   怪物技能等级
     * @return   怪物技能法力消耗=技能基础消耗*(1+(怪物技能等级-1)*0.1)
     */
     public static double monsterUseSkillExpendMagic(int skillBaseExpend,int monsterMagicLevel){
           return skillBaseExpend*(1+(monsterMagicLevel-1)*0.1);
     }

    /**
     * 装备淬炼吞噬其他装备时获得的品阶经验
     * @param equStated       被吞装备境界
     * @param grwonUpEquState   淬炼装备境界
     * @param equPinZhi          被吞装备品质
     * @param grwonUpEquPinZhi    淬炼装备品质
     * @param equPinJie           被吞装备品阶
     * @param grwonUpEquPinJie     淬炼装备品阶
     * @return    装备淬炼吞噬其他装备时获得的品阶经验=淬炼经验基础值*（被吞装备境界/淬炼装备境界）^淬炼经验境界系数
     *                                      *（（被吞装备品质/淬炼装备品质）^淬炼经验品质系数+（被吞装备品阶/淬炼装备品阶）^淬炼经验品阶系数）/2
     */
    public static double getPinJieExpFromEqu(int equStated,int grwonUpEquState,
                                       int equPinZhi,int grwonUpEquPinZhi
            ,int equPinJie,int grwonUpEquPinJie){
      return getPinJieExpFromEqu(0.1, equStated, grwonUpEquState, 0x1, equPinZhi, grwonUpEquPinZhi, 0x1.8p0, equPinJie, grwonUpEquPinJie, 0x1);
    }

    /**
     * 装备淬炼吞噬其他装备时获得的品阶经验
     * @param grwonUpBaseExp    淬炼经验基础值
     * @param equStated       被吞装备境界
     * @param grwonUpEquState   淬炼装备境界
     * @param grwonUpSateModulus   淬炼经验境界系数
     * @param equPinZhi          被吞装备品质
     * @param grwonUpEquPinZhi    淬炼装备品质
     * @param grwonUpEquPinZhiModulus    淬炼经验品质系数
     * @param equPinJie           被吞装备品阶
     * @param grwonUpEquPinJie     淬炼装备品阶
     * @param grwonUpEquPinJieModulus   淬炼经验品阶系数
     * @return    装备淬炼吞噬其他装备时获得的品阶经验=淬炼经验基础值*（被吞装备境界/淬炼装备境界）^淬炼经验境界系数
     *                                      *（（被吞装备品质/淬炼装备品质）^淬炼经验品质系数+（被吞装备品阶/淬炼装备品阶）^淬炼经验品阶系数）/2
     */
    public static double getPinJieExpFromEqu(double grwonUpBaseExp,int equStated,int grwonUpEquState,double grwonUpSateModulus,
                                       int equPinZhi,int grwonUpEquPinZhi,double grwonUpEquPinZhiModulus
                                       ,int equPinJie,int grwonUpEquPinJie,double grwonUpEquPinJieModulus){
        return  Math.pow((grwonUpBaseExp*(equStated/grwonUpEquState)),grwonUpSateModulus)
                *(Math.pow((equPinZhi/grwonUpEquPinZhi),grwonUpEquPinZhiModulus)+Math.pow(equPinJie/grwonUpEquPinJie,grwonUpEquPinJieModulus))/0x2;
    }


   /****************************************************************************************************************** 

    /**
     * 计算玩家出防御消耗的法力值
     * @return
     */
    public static int  ComputeDeffenceLoss(GameCharacter gameCharacter,int cardNum ){
        return cardNum*gameCharacter.getFangreduceMagic();
    }

    /**
     * 使用技能牌
     * 计算法力值的消耗
     * @return 消耗的技能点数
     */
    public static int computeMagicUse(GameCharacter gameCharacter){
        return gameCharacter.getReduceMagic();
    }

    /**
         星级评定按照玩家PVE战斗结束后剩余的气血值、法力盾和战斗回合数计算战斗分数，按照分数评定星级。
         战斗分数=（玩家战斗结束后剩余法力盾/玩家法力盾上限）*110 - 战斗结束时总共进行了几个回合
         若玩家战斗分数>=40，玩家为3星。
         若玩家战斗分数>=10，且<40，为2星。
         若玩家战斗分数<10，为1星。
     * @param lastSheild  玩家战斗结束后剩余法力盾
     * @param maxSheild    玩家法力盾上限
     * @param roudTimes    战斗结束时总共进行了几个回合
     * @return  星级数量
     */
    public static byte stars(int lastSheild,int maxSheild,int roudTimes){
        double fen=((double)lastSheild/maxSheild)* 0x6e-roudTimes;
        if (fen< 0xa){
            return 0x1;
        }
        if (fen>= 0x28){
            return 0x3;
        }else {
            return 0x2;
        }
    }

    /**
     *  获取系统出牌点数
     * @param minCount 纸牌点数最小值
     * @param maxCount 纸牌点数最大值
     * @return
     */
    public static int getCardCount(int minCount,int maxCount){
        return Rnd.newInstance(Rnd.RandomType
                .UNSECURE_VOLATILE).getInt(minCount, maxCount);
    }

    //////////////////////神识牌处理/////////////////////////////////////////////////////////////////////

    /**
     *
     DEFAULT_VALUE.GAME_VALUE.minDizziness=game_config.getInt("minDizziness");
     DEFAULT_VALUE.GAME_VALUE.maxDizziness=game_config.getInt("maxDizziness");
     DEFAULT_VALUE.GAME_VALUE.minHurtSoul=game_config.getInt("minHurtSoul");
     DEFAULT_VALUE.GAME_VALUE.maxHurtSoul=game_config.getInt("maxHurtSoul");
     DEFAULT_VALUE.GAME_VALUE.minSpike =game_config.getInt("minSpike");
     DEFAULT_VALUE.GAME_VALUE.maxSpike=game_config.getInt("maxSpike");
     * 获取神识技能类型
     * @param cardNum   神牌张数
     * @return  0.眩晕 1.以伤换伤 2.秒杀
     *          1、2张神牌是眩晕；3、4张神牌是以伤 换伤；5、6张神牌是秒杀。
     */
   public static int getSoulSkillType(int  cardNum){
      if (cardNum>= Config.DEFAULT_VALUE.GAME_VALUE.minDizziness
              &&cardNum<= Config.DEFAULT_VALUE.GAME_VALUE.maxDizziness){
          return 0x0;    // 眩晕
      }
      if (cardNum >= Config.DEFAULT_VALUE.GAME_VALUE.minHurtSoul
               && cardNum <= Config.DEFAULT_VALUE.GAME_VALUE.maxHurtSoul) {
           return 0x1;  // 以伤换伤
      }
      if (cardNum >= Config.DEFAULT_VALUE.GAME_VALUE.minSpike
               && cardNum <= Config.DEFAULT_VALUE.GAME_VALUE.maxSpike) {
           return 0x2;  // 秒杀
      }
      return 0xffffffff;
   }



    /**
     * 神识技能类型眩晕
     * @param soul1      玩家当前神识值
     * @param soul2      目标神识值
     * @param useSoulCardNum    使用神牌的角色出的神牌张数
     * @param euqAdditional    神识法宝额外附加的概率
     * @return  是否眩晕
     *      神牌眩晕概率	神牌眩晕成功率=玩家当前神识值/（目标神识值+玩家当前神识值）
     *                              *（使用神牌的角色出的神牌张数-眩晕要求的最少神牌数量+1）+神识法宝额外附加眩晕的概率
     */
    public static boolean soulDizzinessSuccess(int soul1,int soul2,int useSoulCardNum,double euqAdditional){
       boolean dizziness=false;
       double rnd= Rnd.newInstance(Rnd.RandomType
                .UNSECURE_VOLATILE).getDouble();  //0 to 1
       double success=(double) soul1/(soul1+soul2)*(useSoulCardNum-Config.DEFAULT_VALUE.GAME_VALUE.dizinnessCardNum+1)+euqAdditional;
       if (success>=rnd){
           dizziness=true;
       }
        return dizziness;
    }



    /**
     *
     * @param soul1 玩家当前神识值
     * @param soul2    目标神识值
     * @param useSoulCardNum  使用神牌的角色出的神牌张数
     * @param euqAdditional    神识法宝额外附加的概率
     * @return
     * 神牌以伤换伤概率	神牌以伤换伤成功率=玩家当前神识值/（目标神识值+玩家当前神识值）
     *                      *（使用神牌的角色出的神牌张数-以伤换伤要求的最少神牌数量+1）/神牌以伤换伤的神识值效果+神识法宝额外附加以伤换伤的概率
     */
    public static boolean soulHurtSuccess(int soul1,int soul2,int useSoulCardNum,double euqAdditional){
        boolean status=false;
        double success=(double)soul1/(soul1+soul2) *(useSoulCardNum-Config.DEFAULT_VALUE.GAME_VALUE.InotherInjuryToInjuryCardNum+1)
                /Config.DEFAULT_VALUE.GAME_VALUE.InotherInjuryToInjurySoulValue+euqAdditional;
        double rnd= Rnd.newInstance(Rnd.RandomType
                .UNSECURE_VOLATILE).getDouble();  //0 to 1
        if (success>=rnd){
            status=true;
        }
        return status;
    }

    /**
     * 神牌秒杀概率/备注	神牌秒杀成功率=玩家当前神识值/（目标神识值+玩家当前神识值）
     *              *（使用神牌的角色出的神牌张数-秒杀要求的最少神牌数量+1）/神牌秒杀的神识值效果+神识法宝额外附加秒杀概率的概率																		神牌秒杀效果对目标造成100%血量伤害
     * @return
     */
    public static boolean spikeSuccess(int soul1,int soul2,int useSoulCardNum,double euqAdditional){
        boolean status=false;
        double success=(double)soul1/(soul1+soul2)*(useSoulCardNum-Config.DEFAULT_VALUE.GAME_VALUE.SpikeCardNum+1)
                /Config.DEFAULT_VALUE.GAME_VALUE.SpikeValue+euqAdditional;
        double rnd= Rnd.newInstance(Rnd.RandomType
                .UNSECURE_VOLATILE).getDouble();  //0 to 1
        if (success>=rnd){
            status=true;
        }
        return status;
    }

    /**
     * 对被攻击方伤害
     * @param targetSheild  目标气血值（法术盾）
     * @return   以伤换伤的伤害
     */
    public static int InotherInjuryToInjuryHurt(int targetSheild){
        return (int) (targetSheild* Config.DEFAULT_VALUE.GAME_VALUE.InotherInjuryToInjuryHurtPercent);
    }

    /**
     * 反伤 （目前的版本不做反伤处理）
     * 攻方伤害
     * @param targetSheild  目标气血值（法术盾）
     * @return
     */
    public static int InotherInjuryToInjuryHurtToSelf(int targetSheild){
       return (int) (targetSheild* Config.DEFAULT_VALUE.GAME_VALUE.InotherInjuryToInjuryHurtPercent* Config.DEFAULT_VALUE.GAME_VALUE.InotherInjuryToInjuryReservedHurtPercent);
    }



    /**
     * PVP: role1---role2     五行
     * PVE: role---Monster    五行
     * monster 来自配置文件
     * role 来自修行的功法
     * 五行是否相克判定
     * 五行相克 ：   金-> 木-> 土-> 水-> 火->金
     *               1    2    3    4   5  1
     * 返回两个五行是否相克
     * @return  1 .相克  a-->b ; 2.不相克 a---b; 3.被克 a<---b;
     * @param a   参照物 a  五行  主动    攻方
     * @param b   被参照物 b  五行         守方
     * 相邻才会相克或则被克
     */
    public static int  grams(int a,int b){
        int result= 0x0;
        if (a== 0x0 ||b==0){
            result= 0x2;
            return result;
        }
        int temp=a-b;
        if (temp== 0x0){
            result= 0x2;
        }else if (temp== 0x1
                ||temp== 0xfffffffc){
            result= 0x3;
        }else if (temp== 0xffffffff
                ||temp== 0x4){
            result= 0x1;
        }else {
            result= 0x2;
        }

        LOGGER.debug("p1>>five:"+a+"::"+"p2>>five:"+b+" result:"+result);
        return result;
    }








    /********出牌类型造成的伤害公式
     * 主动出牌方为：攻方
     *
     * *****************/
    /**
     *
     * 攻击相克
     * @param defence  被攻击方
     * @param attack  攻击方
     * @return  被攻击方造成的法力盾伤害
     *  相克（攻方克制防守方）伤害            =   当前法力盾-（攻方攻击值*110%-防守方防御值）
     */
    public static int attackHurtWithGrams(int defence,int attack){
        return (int)attackHurtWithGrams(defence, attack, 0x1.199999999999ap0);
    }

    /**
     * 攻击相克
     * @param defence  被攻击方
     * @param attack   攻击方
     * @param precnet  攻击方值百分比
     * @return  被攻击方造成的法力盾伤害
     * 相克（攻方克制防守方）伤害            =   （攻方攻击值*110%-防守方防御值）
     */
    public static double attackHurtWithGrams(int defence,int attack,double precnet){
        return  ((attack*precnet-defence));
    }


    /**
     * 攻击不相克
     * @param defence  被攻击方
     * @param attack 攻击方
     * @return  被攻击方造成的法力盾伤害
     * 不相克（功法和防守方互不相克）伤害    =  （攻方攻击值-防守方防御值）
     */
    public static int attackHurtWithUnGrams(int defence,int attack){
        return  attack-defence;
    }

    /**
     *  攻击被克
     * @param defence   被攻击方
     * @param attack   攻击方
     * @return 被攻击方造成的法力盾伤害
     * 被克（攻方被防守方克制）伤害         =    （攻方攻击值*90%-防守方防御值）
     */
    public static int attackHurtWithGramsed(int defence,int attack){
        return (int)attackHurtWithGramsed(defence, attack, 0x1.ccccccccccccdp-1);
    }
    /**
     * 攻击被克
     * @param defence   被攻击方
     * @param attack   攻击方
     * @param precnet   攻击方值百分比
     * @return 被攻击方造成的法力盾伤害
     *     被克（攻方被防守方克制）伤害         =   （攻方攻击值*90%-防守方防御值）
     */
    public static double attackHurtWithGramsed(int defence,int attack,double precnet){
         return (attack*precnet-defence);
    }


    /*********技能牌伤害计算****************************************************************************/
    /**
     * 技牌相克
     * @param defence    被攻击方
     * @param fiveTypeSkillValue   攻方五行技能数值
     * @return  被攻击方造成的法力盾伤害
     *    五行相克的技能伤害 =     （攻方五行技能数值*110%-防守方防御值）
     */
    public static int magicHurtWithGrams(int defence,int fiveTypeSkillValue){
       return   (int)magicHurtWithGrams(defence,fiveTypeSkillValue, 0x1.199999999999ap0);
    }
    /**
     * 技牌相克
     * @param defence     被攻击方
     * @param fiveTypeSkillValue    攻方五行技能数值
     * @param precnet        攻击方值百分比
     * @return      被攻击方造成的法力盾伤害
     * 五行相克的技能伤害 =     （攻方五行技能数值*110%-防守方防御值）
     */
    public static double magicHurtWithGrams(int defence,int fiveTypeSkillValue,double precnet){
        return  ((fiveTypeSkillValue*precnet-defence));
    }

    /**
     * 技牌不相克
     * @param defence    被攻击方
     * @param fiveTypeSkillValue   攻方五行技能数值
     * @return     被攻击方造成的法力盾伤害
     *   五行不相克的技能伤害 =   （攻方五行技能数值-防守方防御值）
     */
    public static int magicHurtWithUnGrams(int defence,int fiveTypeSkillValue){
        return fiveTypeSkillValue-defence;
    }

    /**
     *  技牌被克
     * @param defence       被攻击方
     * @param fiveTypeSkillValue  攻方五行技能数值
     * @return    被攻击方造成的法力盾伤害
     *  五行被克的技能伤害 =  （攻方五行技能数值*90%-防守方防御值）
     */
    public static int magicHurtWithGramsed(int defence,int fiveTypeSkillValue){
            return   (int)magicHurtWithGramsed( defence, fiveTypeSkillValue, 0x1.ccccccccccccdp-1);
    }

    /**
     *  技牌被克
     * @param defence  被攻击方
     * @param fiveTypeSkillValue   攻方五行技能数值
     * @param precnet    攻击方值百分比
     * @return
     *  五行被克的技能伤害 =  （攻方五行技能数值*90%-防守方防御值）
     */
    public static double magicHurtWithGramsed(int defence,int fiveTypeSkillValue,double precnet){
         return (fiveTypeSkillValue*precnet-defence);
    }
   /***********************************************************************************************************************************/


   /**
     * 获取攻方五行技能数值
     * @param levelModel      levelModel
     * @param skillModel      skillModel
     * @return
     */
    public static int  fiveTypeSkillValue(LevelModel levelModel,SkillModel skillModel){
        byte element=skillModel.getElement();//五行属性
        int levelElementNum=0;
        if (element== 0x1){
            levelElementNum=levelModel.getElement1();
        }else if (element== 0x2){
            levelElementNum=levelModel.getElement2();
        }else if (element== 0x3){
            levelElementNum=levelModel.getElement3();
        } else if (element== 0x4){
            levelElementNum=levelModel.getElement4();
        } else if (element== 0x5){
            levelElementNum=levelModel.getElement5();
        }
        return fiveTypeSkillValue(levelElementNum,skillModel.getElementNum(), ScriptFactory.skillModelFastMap.get(skillModel.getId()).getSingleSkillModelFastTable().getFirst().getEffectNum());
    }

    /**
     *
     * @param levelElementNum  {@link com.dc.gameserver.serverCore.model.gamemodel.LevelModel#element1--->elementNum}   element1 value is      elementNum
     * @param skillElementNum   {@link com.dc.gameserver.serverCore.model.gamemodel.SkillModel#element--->elementNum}
     * @return
     *  环境五行满足技能需要的伤害： （关卡五行值（关卡配置）-技能需求五行值（技能配置））/100*技能攻击值+技能攻击值
        环境五行不满足技能需要：     技能攻击值*50%

    若技能需求五行值>环境五行值，攻方五行技能数值=技能基础数值*50%
    若技能需求五行值<=环境五行值，攻方五行技能数值=（环境五行值-技能需求五行值）/100*技能基础数值+技能基础数值

     */
    private static int  fiveTypeSkillValue(int levelElementNum,int skillElementNum,int EffectNum){
        double temp=levelElementNum-skillElementNum;
        if (temp>=0){
            return (int) ((temp/ 0x64)*skillElementNum+skillElementNum);
        }else {
            return  (int)(EffectNum*(0x1.0p-1));
        }
    }


    /**
     * 每一回合 pk对象 恢复法力值
     * @param stateRolerecoverymagic     境界附加的恢复量
     * @param equRolerecoverymagic    装备附加的恢复量
     * @param propsRolerecoverymagic      道具增加的恢复量
     * @return  恢复法力值
     * 恢复法力值=境界附加的恢复量+装备附加的恢复量+道具增加的恢复量
     */
    public static int recoveryMagicForPreRound(int stateRolerecoverymagic,int equRolerecoverymagic,int propsRolerecoverymagic){
        return stateRolerecoverymagic+equRolerecoverymagic+propsRolerecoverymagic;
    }



    /******组装战斗前数据 role monster ***************************/
    /**
     * 任何一个参数改变 都将会该改变对象的属性
     * 战斗前准备气血值
     * @param stateBaseBlood   境界基础血量值
     * @param equBlood         装备附加血量值
     * @param propsBlood       道具附加永久性血量值
     * @param activeBloodInc   活动增加的数值
     * @param activeBlodDec    活动减少的数值
     * @return  战斗前准备气血值
     * 非战斗血量值=境界基础血量值+装备附加血量值+道具附加永久性血量值+活动增加的数值-活动减少的数值
     */
    public static int Blood(int stateBaseBlood,int equBlood,int propsBlood,int activeBloodInc,int activeBlodDec){
        return stateBaseBlood+equBlood+propsBlood+activeBloodInc-activeBlodDec;
    }

    /**
     * 战斗前准备 法术盾
     * @param stateBaseSheild    境界基础法术盾
     * @param equSheild          装备附加法术盾
     * @param propsSheild        道具附加永久性法术盾
     * @param activeShiledInc     活动增加的数值
     * @param activeShiledDec         活动减少的数值
     * @return 战斗前准备法力盾值
     *  非战斗法术盾=境界基础法术盾+装备附加法术盾+道具附加永久性法术盾+活动增加的数值-活动减少的数值
     */
    public static int Sheild(int stateBaseSheild,int equSheild,int propsSheild,int activeShiledInc,int activeShiledDec ){
           return stateBaseSheild+equSheild+propsSheild+activeShiledInc-activeShiledDec;
    }


    /**
     *  战斗前准备 法力值
     * @param stateBaseMagic     境界基础法力值
     * @param equMagic           装备附加法力值
     * @param propsMagic         道具附加永久性法力值
     * @param activeMagicInc     活动增加的数值
     * @param activeMagicDec     活动减少的数值
     * @return  战斗前准备法力值
     * 非战斗法力值=境界基础法力值+装备附加法力值+道具附加永久性法力值+活动增加的数值-活动减少的数值
     */
    public static int Magic(int stateBaseMagic,int equMagic,int propsMagic,int activeMagicInc,int activeMagicDec ){
        return stateBaseMagic+equMagic+propsMagic+activeMagicInc-activeMagicDec;
    }


    /**
     *   战斗前准备 攻击值
     * @param stateBaseAttack     境界基础攻击值
     * @param equAttack           装备附加攻击值
     * @param propsAttack         道具附加永久性攻击值
     * @param activeAttackInc     活动增加的数值
     * @param activeAttackDec     活动减少的数值
     * @return   战斗前准备攻击值
     *  非战斗攻击值=境界基础攻击值+装备附加攻击值+道具附加永久性攻击值+活动增加的数值-活动减少的数值
     */
    public static int Attack(int stateBaseAttack,int equAttack,int propsAttack,int activeAttackInc,int activeAttackDec ){
        return stateBaseAttack+equAttack+propsAttack+activeAttackInc-activeAttackDec;
    }


    /**
     *   战斗前准备 防御值
     * @param stateBaseDefence      境界基础防御值
     * @param equDefence            装备附加防御值
     * @param propsDefence          道具附加永久性防御值
     * @param activeDefenceInc      活动增加的数值
     * @param activeDefenceDec      活动减少的数值
     * @return    战斗前准备 防御值
     * 非战斗防御值=境界基础防御值+装备附加防御值+道具附加永久性防御值+活动增加的数值-活动减少的数值
     */
    public static int Defence(int stateBaseDefence,int equDefence,int propsDefence,int activeDefenceInc,int activeDefenceDec ){
         return stateBaseDefence+equDefence+propsDefence+activeDefenceInc-activeDefenceDec;
    }

    /**
     * 神识值上限
     * @param stateSoual        境界基础神识值
     * @param bookSoual         神识书附加的神识值
     * @param propsSoual        道具附加永久性神识值
     * @param activeSoualInc    活动增加的数值
     * @param activeSoualDec    活动减少的数值
     * @return 神识值上限
     * 神识值上限=境界基础神识值+神识书附加的神识值+道具附加永久性神识值+活动增加的数值-活动减少的数值
     */
    public static int MaxSoual(int stateSoual,int bookSoual,int propsSoual,int activeSoualInc,int activeSoualDec){
          return stateSoual+bookSoual+propsSoual+activeSoualInc-activeSoualDec;
    }

    /**
     * 当前神识值
     * @param MaxSoual          神识值上限
     * @param recoverySoual     被动恢复的神识值  类似“每10分钟自动回复1点神识值”这种
     * @param playerExpend      玩家操作消耗的神识值       “玩家进入副本的关卡会消耗5点神识”、“进行某个任务会消耗1点神识”
     * @return 当前神识值
     *  当前神识值=神识值上限+被动恢复的神识值-玩家操作消耗的神识值
     */
    public static int CurrentSoual(int MaxSoual,int recoverySoual,int playerExpend){
        return MaxSoual+recoverySoual-playerExpend;
    }




    /***************存在buff ，气血 法术盾 攻击 法力 防御 计算公式***********************************************/
    /**
     * 存在buff ,blood计算
     * @param blood  战斗血量值
     * @param buffValue  buff附加数值        skill ,道具配置        buff附加数值
     * @param buffPrencet  buff附加百分比
     * @return  blood    value
     * 总血量=（战斗血量值+buff附加数值）*buff附加百分比
     */
    public static int pkBlood(int blood,int buffValue,double buffPrencet){
        return (int) ((blood+buffValue)*buffPrencet);
    }


    /**
     * 存在buff ,Shiled计算
     * @param Shiled    战斗法术盾
     * @param buffValue  buff附加数值
     * @param buffPrencet  buff附加百分比    skill ,道具配置        buff附加数值
     * @return   Shiled    value
     * 法术盾=（法术值+buff附加数值）*buff附加百分比
     */
    public static int pkShiled(int Shiled,int buffValue,double buffPrencet){
        return (int) ((Shiled+buffValue)*buffPrencet);
    }

    /**
     *  存在buff ,magic计算
     * @param magic   战斗法力值
     * @param buffValue   buff附加数值        skill ,道具配置        buff附加数值
     * @param buffPrencet  buff附加百分比
     * @return    magic value
     *  法力值=（法力值+buff附加数值）*buff附加百分比
     */
    public static int pkMagic(int magic,int buffValue,double buffPrencet){
        return (int) ((magic+buffValue)*buffPrencet);
    }

    /**
     * 存在buff ,attack计算
     * @param attack     攻击值
     * @param buffValue       buff附加数值
     * @param buffPrencet     buff附加百分比
     * @return  attack value
     * 攻击=（攻击值+buff附加数值）*buff附加百分比
     */
    public static int pkAttack(int attack,int buffValue,double buffPrencet){
        return (int) ((attack+buffValue)*buffPrencet);
    }


    /**
     * 存在buff ,defence计算
     * @param defence      防御值
     * @param buffValue     buff附加数值
     * @param buffPrencet  buff附加百分比
     * @return   defence value
     * 防御=（防御值+buff附加数值）*buff附加百分比
     */
    public static int pkDefence(int defence,int buffValue,double buffPrencet){
        return (int) ((defence+buffValue)*buffPrencet);
    }


    public static void main(String[]args){
//        * 五行相克 ：   金-> 木-> 土-> 水-> 火->金
//                *       1    2    3    4   5  1
//        1 .相克  a-->b ; 2.不相克 a---b; 3.被克 a<---b;
         System.out.println(grams(1,2));

    }


}
